package com.itfreer.arcgis.utils;

import android.graphics.Color;

import com.esri.arcgisruntime.arcgisservices.LabelDefinition;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.data.FeatureQueryResult;
import com.esri.arcgisruntime.data.FeatureTable;
import com.esri.arcgisruntime.data.Field;
import com.esri.arcgisruntime.data.QueryParameters;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.geometry.GeometryEngine;
import com.esri.arcgisruntime.geometry.GeometryType;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
import com.esri.arcgisruntime.symbology.SimpleRenderer;
import com.esri.arcgisruntime.symbology.UniqueValueRenderer;
import com.itfreer.arcgis.query.GetSelectFeatureListener;
import com.itfreer.arcgis.symbol.SymbolStyleType;
import com.itfreer.arcgis.symbol.SymbolUtils;
import com.itfreer.data.dictionary.DictionaryManage;
import com.itfreer.utils.common.ColorUtils;
import com.itfreer.utils.common.JSONUtils;
import com.itfreer.utils.common.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 图层对象
 */
public class LayerUtils {
    /**
     * 根据矢量数据要素对象创建图层对象
     *
     * @param featureTable
     *            数据对象
     * @return
     */
    public static FeatureLayer CreateFeatureLayerFormTable(FeatureTable featureTable) {
        try {
            // 构建FeatureLayer
            FeatureLayer featureLayer = new FeatureLayer(featureTable);
            return featureLayer;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 更新点图层样式
     *
     * @param featureLayer
     */
    public static void UpdatePointLayerStyle(FeatureLayer featureLayer, String hexColor, float size) {
        if (featureLayer == null || featureLayer.getFeatureTable().getGeometryType() != GeometryType.POINT)
            return;
        featureLayer.setRenderer(SymbolUtils.GetRenderer(
                SymbolUtils.GetPointSymbol(SymbolStyleType.PointType.CIRCLE, ColorUtils.Hex2Int(hexColor), size)));
    }

    /**
     * 更新面图层样式
     *
     * @param featureLayer
     */
    public static void UpdateLineLayerStyle(FeatureLayer featureLayer, String hexColor, float size) {
        if (featureLayer == null || featureLayer.getFeatureTable().getGeometryType() != GeometryType.POLYLINE)
            return;
        featureLayer.setRenderer(SymbolUtils.GetRenderer(
                SymbolUtils.GetPolylineSymbol(SymbolStyleType.PolylineType.SOLID, ColorUtils.Hex2Int(hexColor), size)));
    }

    /**
     * 更新面图层样式
     *
     * @param featureLayer
     */
    public static void UpdatePolygonLayerStyle(FeatureLayer featureLayer, String hexColor, float size,
                                               SimpleLineSymbol outLineSymbol) {
        if (featureLayer == null || featureLayer.getFeatureTable().getGeometryType() != GeometryType.POLYGON)
            return;
        featureLayer.setRenderer(SymbolUtils.GetRenderer(SymbolUtils.GetPolygonSymbol(SymbolStyleType.PolygonType.SOLID,
                ColorUtils.Hex2Int(hexColor), outLineSymbol)));
    }

    /**
     * 重置图层样式
     *
     * @param featureLayer
     */
    public static void ResetSymbol(FeatureLayer featureLayer) {
        if (featureLayer == null)
            return;

        featureLayer.resetRenderer();
    }

    /**
     * 点选要素
     *
     * @param point
     *            点对象
     * @param mapView
     *            地图对象
     * @param featureLayer
     *            图层对象
     */
    public static ListenableFuture<FeatureQueryResult> SelectFeatures(Point point, MapView mapView, FeatureLayer featureLayer) {
        QueryParameters query = new QueryParameters();
        query.setGeometry(point);
        query.setSpatialRelationship(QueryParameters.SpatialRelationship.WITHIN);
        query.setMaxFeatures(1);
        return featureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW);
    }

    /**
     * 点选要素
     *
     * @param envelope
     *            矩形对象
     * @param mapView
     *            地图对象
     * @param featureLayer
     *            图层对象
     */
    public static void SelectFeatures(Envelope envelope, MapView mapView, FeatureLayer featureLayer)
    {
        //如果坐标不一致，则进行坐标转换，转成图层坐标，并且创建新的范围，不知道为啥，直接用查询不到结果
        if(envelope.getSpatialReference().getWkid() != featureLayer.getSpatialReference().getWkid())
            envelope = (Envelope) GeometryEngine.project(envelope ,featureLayer.getSpatialReference());
        Envelope resultEnvelope = new Envelope(new Point(envelope.getXMin(),envelope.getYMax(),envelope.getSpatialReference()),
                new Point(envelope.getXMax(),envelope.getYMin(),envelope.getSpatialReference()));
        QueryParameters query = new QueryParameters();
        query.setGeometry(resultEnvelope);
        query.setSpatialRelationship(QueryParameters.SpatialRelationship.INTERSECTS);
        featureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW);
    }

    /**
     * 获取选中要素并回调
     *
     * @param featureLayer
     */
    public static void GetSelectFeature(final FeatureLayer featureLayer, final GetSelectFeatureListener listener) {
        if (featureLayer == null || listener == null)
            return;
        final ListenableFuture<FeatureQueryResult> selected = featureLayer.getSelectedFeaturesAsync();
        selected.addDoneListener(new Runnable() {
            @Override
            public void run() {
                try {
                    listener.execute(featureLayer, selected);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 显示图层标注
     *
     * @param featureLayer
     * @param color
     * @param showField
     */
    public static void ShowFeatureLayerLabel(FeatureLayer featureLayer, String color, Field showField) {
        int[] rgbColor = ColorUtils.Hex2Rgb(color);
        String addressLabelsJson = "{" + "\"labelExpressionInfo\": {" + // Define a labeling expression that will show
                // the address attribute value
                "\"expression\": \"return $feature." + showField.getName() + ";\"},"
                + "\"labelPlacement\": \"esriServerPolygonPlacementAlwaysHorizontal\"," + // Align labels horizontally
                "\"symbol\": {" + // Use a green bold text symbol
                "\"color\": [" + rgbColor[0] + "," + rgbColor[1] + "," + rgbColor[2] + ",255],"
                + "\"font\": {\"size\": 18, \"weight\": \"bold\"}," + "\"type\": \"esriTS\"}" + "}";

        // Create a new LabelDefintion object using the static FromJson method
        LabelDefinition labelDef = LabelDefinition.fromJson(addressLabelsJson);

        // Clear the current collection of label definitions (if any)
        featureLayer.getLabelDefinitions().clear();

        // Add this label definition to the collection
        featureLayer.getLabelDefinitions().add(labelDef);

        // Make sure labeling is enabled for the layer
        featureLayer.setLabelsEnabled(true);
    }

    /**
     * 隐藏图层标注
     *
     * @param featureLayer
     */
    public static void HiddenFeatureLayerLabel(FeatureLayer featureLayer) {
        featureLayer.getLabelDefinitions().clear();
        featureLayer.setLabelsEnabled(false);
    }

    /**
     * 添加标注
     * @param featureLayer
     * @param strLabelDefinition
     */
    public static  void AddFeatureLayerLabel(FeatureLayer featureLayer,String strLabelDefinition) {
        // Create a new LabelDefintion object using the static FromJson method
        LabelDefinition labelDef = LabelDefinition.fromJson(strLabelDefinition);

        // Clear the current collection of label definitions (if any)
        featureLayer.getLabelDefinitions().clear();

        // Add this label definition to the collection
        featureLayer.getLabelDefinitions().add(labelDef);

        // Make sure labeling is enabled for the layer
        featureLayer.setLabelsEnabled(true);
    }

    /***
     * 添加渲染
     * @param featureLayer
     * @param jsonStr
     */
    public static void AddRenderer(FeatureLayer featureLayer,String jsonStr) {
        try {
            if (StringUtils.IsNullOrSpace(jsonStr)) {
                AddDefaultRenderer(featureLayer);
            } else {
                HashMap map = JSONUtils.toBean(jsonStr, HashMap.class);
                if(map == null || map.isEmpty()){
                    return;
                }
                Object rederObj = map.get("rederer");
                if (StringUtils.IsNullOrEmpty(rederObj)) {
                    AddDefaultRenderer(featureLayer);
                }else if ("Simple".equals(rederObj.toString())){
                    AddSimpleRenderer(featureLayer, map);
                } else if ("Unique".equals(rederObj.toString())) {
                    AddUniqueValueRenderer(featureLayer, map);
                } else {
                    AddDefaultRenderer(featureLayer);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加简单渲染
     * @param featureLayer
     * @param map
     */
    public static void AddSimpleRenderer(FeatureLayer featureLayer,HashMap map){

        SimpleRenderer sr = new SimpleRenderer();
        Object fillColorObj =  map.get("fillColor");

        //初始化无颜色
        int dFillColor = 0;
        if(StringUtils.IsNullOrEmpty(fillColorObj)){
            fillColorObj = "#FFCDE9F7";
            dFillColor = Color.parseColor(fillColorObj.toString());
        }else if("0".equals(fillColorObj.toString())){

        }else{
            dFillColor = Color.parseColor(fillColorObj.toString());
        }


        //设置默认填充样式
        Object fillStyle = map.get("fillStyle");
        if(StringUtils.IsNullOrEmpty(fillStyle)){
            fillStyle = "SOLID";
        }

        //设置默认边框颜色的 16 进制的值
        Object lineColorObj =  map.get("lineColor");
        //初始化无颜色
        int lineColor = 0;
        if(StringUtils.IsNullOrEmpty(lineColorObj)){
            lineColorObj = "#FF6E6E6E";
            lineColor = Color.parseColor(lineColorObj.toString());
        }else if("0".equals(lineColorObj.toString())){

        }else{
            lineColor = Color.parseColor(lineColorObj.toString());
        }

        //设置默认边框线条样式  DASH,DASH_DOT,DASH_DOT_DOT,DOT,SOLID,NULL;
        Object lineStyle = map.get("lineStyle");
        if(StringUtils.IsNullOrEmpty(lineStyle)){
            lineStyle = "SOLID";
        }

        //设置默认边框线条的宽度
        Object lineWidthObj = map.get("lineWidth");
        if(StringUtils.IsNullOrEmpty(lineWidthObj)){
            lineWidthObj = 0.4;
        }
        float lineWidth = Float.parseFloat(lineWidthObj.toString());
        SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.valueOf(fillStyle.toString()),
                dFillColor,new SimpleLineSymbol(SimpleLineSymbol.Style.valueOf(lineStyle.toString()), lineColor, lineWidth));
        //简单渲染
        featureLayer.setRenderer(sr);
        sr.setSymbol(fillSymbol);
    }

    /**
     * 添加默认渲染
     * @param featureLayer
     */
    public static void AddDefaultRenderer(FeatureLayer featureLayer){
        SimpleRenderer sr = new SimpleRenderer();
        int fillColor = ColorUtils.Hex2Int("#FFCDE9F7");
        int lineColor = ColorUtils.Hex2Int("#FF6E6E6E");
        SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID,
                fillColor, new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID,lineColor, (float)0.4));
        featureLayer.setRenderer(sr);
        sr.setSymbol(fillSymbol);
    }

    /**
     * 添加唯一值渲染
     * @param featureLayer
     * @param map 渲染对象
     */
    public static void AddUniqueValueRenderer(FeatureLayer featureLayer,HashMap map) {
        UniqueValueRenderer uniqueValueRenderer = new UniqueValueRenderer();
        // Set the field to use for the unique values
        Object fieldListObj = map.get("fieldList");
        if(StringUtils.IsNullOrEmpty(fieldListObj)){
            return;
        }
        /**
         * 字段列表
         */
        List<String> fieldList = (ArrayList<String>)fieldListObj;
        uniqueValueRenderer.getFieldNames().addAll(fieldList);

        //设置默认的填充颜色的 16 进制的值
        Object dFillColorObj =  map.get("fillColor");
        //初始化无颜色
        int dFillColor = 0;
        if(StringUtils.IsNullOrEmpty(dFillColorObj)){
            dFillColorObj = "#FFCDE9F7";
            dFillColor = Color.parseColor(dFillColorObj.toString());
        }else if("0".equals(dFillColorObj.toString())){

        }else{
            dFillColor = Color.parseColor(dFillColorObj.toString());
        }

        //设置默认填充样式
        Object dFillStyle = map.get("fillStyle");
        if(StringUtils.IsNullOrEmpty(dFillStyle)){
            dFillStyle = "SOLID";
        }

        //设置默认边框颜色的 16 进制的值
        Object dLineColorObj =  map.get("lineColor");
        //初始化无颜色
        int dLineColor = 0;
        if(StringUtils.IsNullOrEmpty(dLineColorObj)){
            dLineColorObj = "#FF6E6E6E";
            dLineColor = Color.parseColor(dLineColorObj.toString());
        }else if("0".equals(dLineColorObj.toString())){

        }else{
            dLineColor = Color.parseColor(dLineColorObj.toString());
        }

        //设置默认边框线条样式  DASH,DASH_DOT,DASH_DOT_DOT,DOT,SOLID,NULL;
        Object dLineStyle = map.get("lineStyle");
        if(StringUtils.IsNullOrEmpty(dLineStyle)){
            dLineStyle = "SOLID";
        }

        //设置默认边框线条的宽度
        Object dLineWidthObj = map.get("lineWidth");
        if(StringUtils.IsNullOrEmpty(dLineWidthObj)){
            dLineWidthObj = 0.4;
        }
        float dLineWidth = Float.parseFloat(dLineWidthObj.toString());

        //设置默认值样式
        SimpleFillSymbol defaultFillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.valueOf(dFillStyle.toString()),
                dFillColor, new SimpleLineSymbol(SimpleLineSymbol.Style.valueOf(dLineStyle.toString()), dLineColor, dLineWidth));

        // 添加默认的样式
        uniqueValueRenderer.setDefaultSymbol(defaultFillSymbol);
        //设置默认的label
        Object dLabel = map.get("label");
        if(StringUtils.IsNullOrEmpty(dLabel)){
            //设置默认label
            uniqueValueRenderer.setDefaultLabel(dLabel.toString());
        }

        //获取渲染对象
        Object render = map.get("rendererList");
        if(!StringUtils.IsNullOrEmpty(render)){
            List<HashMap<String, Object>> rendererList = (ArrayList<HashMap<String, Object>>)render;
            if(rendererList !=null && rendererList.size() >=1){
                for (int i = 0; i < rendererList.size(); i++) {

                    //设置值
                    List<Object> valueList = (ArrayList<Object>)rendererList.get(i).get("valueList");

                    Object description = rendererList.get(i).get("description");
                    if(StringUtils.IsNullOrEmpty(description)){
                        description = "";
                    }

                    Object label = rendererList.get(i).get("label");
                    if(StringUtils.IsNullOrEmpty(label)){
                        label = "";
                    }

                    // 设置填充颜色的 16 进制的值
                    Object fillColorObj =  rendererList.get(i).get("fillColor");
                    int fillColor = 0;
                    if(StringUtils.IsNullOrEmpty(fillColorObj)){
                        fillColorObj = dFillColorObj;
                        if("0".equals(fillColorObj.toString())){

                        }else{
                            fillColor = Color.parseColor(fillColorObj.toString());
                        }
                    }else if("0".equals(fillColorObj.toString())){

                    }else{
                        fillColor = Color.parseColor(fillColorObj.toString());
                    }

                    //填充样式  BACKWARD_DIAGONAL,FORWARD_DIAGONAL,DIAGONAL_CROSS,HORIZONTAL,VERTICAL,CROSS,SOLID,NULL;
                    //设置填充样式
                    Object fillStyle = rendererList.get(i).get("fillStyle");
                    if(StringUtils.IsNullOrEmpty(fillStyle)){
                        fillStyle = dFillStyle;
                    }

                    // 设置边框线条颜色的 16 进制的值
                    Object lineColorObj =  rendererList.get(i).get("lineColor");
                    //默认无颜色
                    int lineColor = 0;
                    if(StringUtils.IsNullOrEmpty(lineColorObj)){
                        lineColorObj = dLineColorObj;
                        if("0".equals(lineColorObj.toString())){

                        }else{
                            lineColor = Color.parseColor(lineColorObj.toString());
                        }
                    }else if("0".equals(lineColorObj.toString())){

                    }else{
                        lineColor = Color.parseColor(lineColorObj.toString());
                    }

                    //设置线条样式  DASH,DASH_DOT,DASH_DOT_DOT,DOT,SOLID,NULL;
                    Object lineStyle = rendererList.get(i).get("lineStyle");
                    if(StringUtils.IsNullOrEmpty(lineStyle)){
                        lineStyle = dLineStyle;
                    }

                    //设置边框线条的宽度
                    Object lineWidthObj = rendererList.get(i).get("lineWidth");
                    if(StringUtils.IsNullOrEmpty(lineWidthObj)){
                        lineWidthObj = dLineWidthObj;
                    }
                    //获取线条的宽度
                    float lineWidth = Float.parseFloat(lineWidthObj.toString());

                    //添加样式
                    SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.valueOf(fillStyle.toString()),
                            fillColor, new SimpleLineSymbol(SimpleLineSymbol.Style.valueOf(lineStyle.toString()), lineColor, lineWidth));

                    uniqueValueRenderer.getUniqueValues().add(new UniqueValueRenderer.UniqueValue(description.toString(), label.toString(), fillSymbol, valueList));
                }
                // Set the renderer on the feature layer
                featureLayer.setRenderer(uniqueValueRenderer);
            }
        }
    }

    /**
     * 处理标注翻译
     * @param dicJsonStr 字典字符串
     * @param strLabelDefinition 标注字符串
     * @return
     */
    public static String replaceDicnaryValue(String dicJsonStr,String strLabelDefinition){
        try {
            if (!StringUtils.IsNullOrSpace(dicJsonStr)) {
                HashMap map = JSONUtils.toBean(dicJsonStr, HashMap.class);
                if(map != null && ! map.isEmpty()){
                    //需要翻译的字段对象
                    Object dicObject = map.get("dicList");
                    if(!StringUtils.IsNullOrEmpty(dicObject)){
                        List<HashMap<String, String>> dicList = (ArrayList<HashMap<String, String>>)dicObject;
                        if(dicList != null && dicList.size()>=1){
                            for (int i = 0; i < dicList.size(); i++){
                                String dicName = dicList.get(i).get("dicName");
                                String dictionary= DictionaryManage.instance.getDictionaryString(dicName);
                                if(StringUtils.IsNullOrEmpty(dictionary)){
                                    dictionary = "'1','1'";
                                }
                                String dicValue = dicList.get(i).get("dicValue");
                                if(!StringUtils.IsNullOrEmpty(dictionary)){
                                    strLabelDefinition = strLabelDefinition.replace(dicValue,dictionary);
                                }
                            }
                            return  strLabelDefinition;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strLabelDefinition;
    }
}

